-- run_tree
--
local import = import
---@type behavior_ret
local bret = import('bt/bt_plugin/behavior3/behavior_ret')
---@type load_tree
local load_tree = import('bt/bt_framework/func/load_tree')
---@type TREE_TYPE_CONFIG
local TREE_TYPE_CONFIG = import('bt/custom_node/enum_type_cfg/TREE_TYPE_CONFIG')
local TYPE_OPTIONS = TREE_TYPE_CONFIG.TYPE_OPTIONS
local CONDITION_TYPE_OPTIONS = TREE_TYPE_CONFIG.CONDITION_TYPE_OPTIONS
local TYPE = TREE_TYPE_CONFIG.TYPE
local CONFIG = TREE_TYPE_CONFIG.CONFIG
local RUN_TREE_DATA_KEY = TREE_TYPE_CONFIG.RUN_TREE_DATA_KEY

local M = {
    name = "run_tree",
    type = "Action",
    desc = "运行指定树",
    args = {
        {
            name = "conditionType",
            type = "enum?",
            desc = "条件",
            options = CONDITION_TYPE_OPTIONS
        },
        {
            name = "actionType",
            type = "enum",
            desc = "行为",
            options = TYPE_OPTIONS
        },
    },
    input = { "条件变量?", "行为变量?" },
    doc = [[
        不能在子树中再次调用此节点
        条件不为空时，返回成功时运行行为子树
        否则直接运行行为树
    ]]
}

local function run_tree(runCount, treeKey, node, env, value)
    local ctx = env.ctx
    local owner = env.owner
    local cfgData = CONFIG[treeKey]
    if cfgData then
        local treeName = node.tree.name
        local key = string.format("%s:%s:%s:", treeName, node.id, "RUN_TREE")
        local innerVar = env:get_inner_var(node, key)
        local tree = load_tree.get_tree(key .. treeKey, cfgData.filePath, ctx, owner)
        if not innerVar then
            tree:interrupt()
            innerVar = { actionType = node.args.actionType, data = value }
            env:set_inner_var(node, key, innerVar)
        end
        innerVar.runCount = runCount + 1
        tree:set_env(RUN_TREE_DATA_KEY, innerVar)
        local ret = tree:run()
        if ret ~= bret.RUNNING then
            env:set_inner_var(node, key, nil)
        end
        return ret, true
    else
        print(string.format("树【%s】 节点ID【%s】 【%s】找不到配置", node.tree.name, node.id, treeKey))
    end
    return bret.FAIL, false
end

function M.run(node, env, conditionData, actionData)
    local treeName = node.tree.name
    local run_data = env[RUN_TREE_DATA_KEY]
    local runCount = run_data and run_data.runCount or 0
    if runCount >= 2 then
        print(string.format("树【%s】 节点ID【%s】 run_tree发现循环调用", treeName, node.id))
        return bret.ABORT
    end
    local conditionType = node.args.conditionType
    local actionType = node.args.actionType
    if conditionType and conditionType ~= TYPE.NONE then
        local ret, res = run_tree(runCount, conditionType, node, env, conditionData)
        if not res then
            print(string.format("树【%s】 节点ID【%s】 条件运行失败", treeName, node.id))
            return bret.FAIL
        end
        if ret == bret.FAIL or ret == bret.RUNNING then
            if ret == bret.RUNNING then
                return ret
            end
            return bret.FAIL
        end
    end
    local ret, res = run_tree(runCount, actionType, node, env, actionData)
    if not res then
        return bret.FAIL
    end
    return ret
end

return M
